package wang_wen_wen;

import java.util.Scanner;

public class WANG_WEN_WEN_TH_Q1 {
        /*
        用数组模拟环形队列：
        首先我们要什么（定义）：队列有头指针和尾指针，还有最大容量，因此我们要创建front,rear,maxSize变量，判断队列中数据个数num，
        再定义一个数组用来模拟队列
        再然后我们要做什么（方法）：创建一个队列，进行增删查及队列复用
        并测试效果
        重点：增加就是尾指针向后移动，并给该下标的数组赋值，但是要注意是否到最大值，可以留一个空的作为约定方便判断正反，判断队列满不能直接rear==front，
        要(rear+1)%maxSize==front，加一就是加上最后一个空的约定
                  删除（取出数据）就是头指针向后移，如果是取出就可以再加一个返回该数组下标的值，删除则可以不返回，但是要注意判断该队列是否为空rear==front
                  查找（显示数据）就是尾指针减去头指针，(rear-front+maxSize)%maxSize
        注意：判断为空就是判断 头指针和尾指针是否相等 rear == front
                  判断队列满不能直接rear==front，要(rear+1)%maxSize==front
        */
        public static void main(String[] args){
            //创建一个队列
            ArrayQueue arrQueue = new ArrayQueue(3);
            char key = ' ';//接收输入
            Scanner scanner = new Scanner(System.in);//
            boolean loop = true;//默认一个循环，死循环
            //输出一个菜单
            while(loop){
                System.out.println("s(show):显示队列");
                System.out.println("e(exit):退出程序");
                System.out.println("a(add):添加数据到队列");
                System.out.println("d(delete):从队列取出数据");
                System.out.println("h(head):查看队列头的数据");
                key = scanner.next().charAt(0);//接收一个字符
                switch(key){
                    case's':
                        arrQueue.showQueue();
                        break;
                    case'e':
                        scanner.close();
                        loop = false;
                        break;
                    case'a':
                        System.out.println("输入一个数：");
                        int value = scanner.nextInt();
                        arrQueue.addQueue(value);
                        break;
                    case'd':
                        try{
                            int res = arrQueue.deleteQueue();
                            System.out.println("取出的数据是："+res);
                        }catch(Exception e){
                            System.out.println(e.getMessage());
                        }
                        break;
                    case'h':
                        try{
                            int res = arrQueue.headQueue();
                            System.out.println("队列头的数据是："+res);
                        }catch(Exception e){
                            System.out.println(e.getMessage());
                        }
                        break;
                    default:
                        break;
                }
            }
            System.out.println("退出成功！");
        }
    }
    class ArrayQueue{
        private int maxSize;//表示数组的最大容量
        private int front;//队列头
        private int rear;//队列尾
        private int[] arr;//该数组用于存放数据，模拟队列

        //创建队列
        public ArrayQueue(int arrMaxSize){
            maxSize = arrMaxSize;
            arr = new int[maxSize];
            front = 0;//指向队列头部，分析出front是指向队列头部的前一个位置
            rear =  0;//指向队列尾部，指向队列尾的数据（即就是队列倒数第二个数据）
        }
        //判断队列是否满
        public boolean isFull(){
            return (rear+1)%maxSize == front;
        }
        //判断队列是否空
        public boolean isEmpty(){
            return rear == front;
        }
        //添加数据到队列
        public boolean addQueue(int n){
            if(isFull()){
                System.out.println("队列满，加入失败");
                return false;
            }
            //直接将数据加入
            arr[rear] = n;
            //将rear后移，这里必须考虑取模
            rear=(rear+1)%maxSize;
            return true;
        }
        //显示队列的所有数据
        public void showQueue(){
            //遍历
            if(isEmpty()){
                System.out.println("队列空");
                return;
            }
            int number = (rear-front+maxSize)%maxSize;
            int maxnumber = front + number;
            for(int i = front;i < maxnumber;i++){
                System.out.println("arr["+i+"]="+arr[i]);
            }
        }
        //删除数据就是取出数据
        public int deleteQueue(){
            if(isEmpty()){
                //System.out.println("队列空，删除失败");
                throw new RuntimeException("队列空，不能取数组");
                //return;
            }
            //这里需要分析出front是指向队列的第一个元素
            //1.先把front对应的值保留到一个临时变量
            //2.将front后移
            //3.将临时保存的变量返回
            front =(front+1) % maxSize;//让front后移
            int number = arr[front];
            return number;
        }
        //显示队列的头部数据，不是取数据
        public int headQueue(){
            //判断
            if(isEmpty()){
                //System.out.println("队列空");
                throw new RuntimeException("队列空");
            }
            return arr[front];
        }
    }
